//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_exported import SotoCore

/// Service object for interacting with AWS ControlCatalog service.
///
/// Welcome to the Control Catalog API reference. This guide is for developers who need detailed information about how to programmatically identify and filter the common controls and related metadata that are available to Amazon Web Services customers. This API reference provides descriptions, syntax, and usage examples for each of the actions and data types that are supported by Control Catalog.  Use the following links to get started with the Control Catalog API:    Actions: An alphabetical list of all Control Catalog API operations.    Data types: An alphabetical list of all Control Catalog data types.    Common parameters: Parameters that all operations can use.    Common errors: Client and server errors that all operations can return.
public struct ControlCatalog: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the ControlCatalog client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - middleware: Middleware chain used to edit requests before they are sent and responses before they are decoded 
    ///     - timeout: Timeout value for HTTP requests
    ///     - byteBufferAllocator: Allocator for ByteBuffers
    ///     - options: Service options
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        middleware: AWSMiddlewareProtocol? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            serviceName: "ControlCatalog",
            serviceIdentifier: "controlcatalog",
            serviceProtocol: .restjson,
            apiVersion: "2018-05-10",
            endpoint: endpoint,
            errorType: ControlCatalogErrorType.self,
            middleware: middleware,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }





    // MARK: API Calls

    /// Returns details about a specific control, most notably a list of Amazon Web Services Regions where this control is supported. Input a value for the ControlArn parameter, in ARN form. GetControl accepts controltower or controlcatalog control ARNs as input. Returns a controlcatalog ARN format. In the API response, controls that have the value GLOBAL in the Scope field do not show the DeployableRegions field, because it does not apply. Controls that have the value REGIONAL in the Scope field return a value for the DeployableRegions field, as shown in the example.
    @Sendable
    @inlinable
    public func getControl(_ input: GetControlRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> GetControlResponse {
        try await self.client.execute(
            operation: "GetControl", 
            path: "/get-control", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns details about a specific control, most notably a list of Amazon Web Services Regions where this control is supported. Input a value for the ControlArn parameter, in ARN form. GetControl accepts controltower or controlcatalog control ARNs as input. Returns a controlcatalog ARN format. In the API response, controls that have the value GLOBAL in the Scope field do not show the DeployableRegions field, because it does not apply. Controls that have the value REGIONAL in the Scope field return a value for the DeployableRegions field, as shown in the example.
    ///
    /// Parameters:
    ///   - controlArn: The Amazon Resource Name (ARN) of the control. It has one of the following formats:  Global format   arn:{PARTITION}:controlcatalog:::control/{CONTROL_CATALOG_OPAQUE_ID}   Or Regional format   arn:{PARTITION}:controltower:{REGION}::control/{CONTROL_TOWER_OPAQUE_ID}  Here is a more general pattern that covers Amazon Web Services Control Tower and Control Catalog ARNs:  ^arn:(aws(?:[-a-z]*)?):(controlcatalog|controltower):[a-zA-Z0-9-]*::control/[0-9a-zA-Z_\\-]+$
    ///   - logger: Logger use during operation
    @inlinable
    public func getControl(
        controlArn: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetControlResponse {
        let input = GetControlRequest(
            controlArn: controlArn
        )
        return try await self.getControl(input, logger: logger)
    }

    /// Returns a paginated list of common controls from the Amazon Web Services Control Catalog. You can apply an optional filter to see common controls that have a specific objective. If you don’t provide a filter, the operation returns all common controls.
    @Sendable
    @inlinable
    public func listCommonControls(_ input: ListCommonControlsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListCommonControlsResponse {
        try await self.client.execute(
            operation: "ListCommonControls", 
            path: "/common-controls", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns a paginated list of common controls from the Amazon Web Services Control Catalog. You can apply an optional filter to see common controls that have a specific objective. If you don’t provide a filter, the operation returns all common controls.
    ///
    /// Parameters:
    ///   - commonControlFilter: An optional filter that narrows the results to a specific objective. This filter allows you to specify one objective ARN at a time. Passing multiple ARNs in the CommonControlFilter isn’t supported.
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - nextToken: The pagination token that's used to fetch the next set of results.
    ///   - logger: Logger use during operation
    @inlinable
    public func listCommonControls(
        commonControlFilter: CommonControlFilter? = nil,
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListCommonControlsResponse {
        let input = ListCommonControlsRequest(
            commonControlFilter: commonControlFilter, 
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.listCommonControls(input, logger: logger)
    }

    /// Returns a paginated list of control mappings from the Control Catalog. Control mappings show relationships between controls and other entities, such as common controls or compliance frameworks.
    @Sendable
    @inlinable
    public func listControlMappings(_ input: ListControlMappingsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListControlMappingsResponse {
        try await self.client.execute(
            operation: "ListControlMappings", 
            path: "/list-control-mappings", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns a paginated list of control mappings from the Control Catalog. Control mappings show relationships between controls and other entities, such as common controls or compliance frameworks.
    ///
    /// Parameters:
    ///   - filter: An optional filter that narrows the results to specific control mappings based on control ARNs, common control ARNs, or mapping types.
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - nextToken: The pagination token that's used to fetch the next set of results.
    ///   - logger: Logger use during operation
    @inlinable
    public func listControlMappings(
        filter: ControlMappingFilter? = nil,
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListControlMappingsResponse {
        let input = ListControlMappingsRequest(
            filter: filter, 
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.listControlMappings(input, logger: logger)
    }

    /// Returns a paginated list of all available controls in the Control Catalog library. Allows you to discover available controls. The list of controls is given as structures of type controlSummary. The ARN is returned in the global controlcatalog format, as shown in the examples.
    @Sendable
    @inlinable
    public func listControls(_ input: ListControlsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListControlsResponse {
        try await self.client.execute(
            operation: "ListControls", 
            path: "/list-controls", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns a paginated list of all available controls in the Control Catalog library. Allows you to discover available controls. The list of controls is given as structures of type controlSummary. The ARN is returned in the global controlcatalog format, as shown in the examples.
    ///
    /// Parameters:
    ///   - filter: An optional filter that narrows the results to controls with specific implementation types or identifiers. If you don't provide a filter, the operation returns all available controls.
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - nextToken: The pagination token that's used to fetch the next set of results.
    ///   - logger: Logger use during operation
    @inlinable
    public func listControls(
        filter: ControlFilter? = nil,
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListControlsResponse {
        let input = ListControlsRequest(
            filter: filter, 
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.listControls(input, logger: logger)
    }

    /// Returns a paginated list of domains from the Control Catalog.
    @Sendable
    @inlinable
    public func listDomains(_ input: ListDomainsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListDomainsResponse {
        try await self.client.execute(
            operation: "ListDomains", 
            path: "/domains", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns a paginated list of domains from the Control Catalog.
    ///
    /// Parameters:
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - nextToken: The pagination token that's used to fetch the next set of results.
    ///   - logger: Logger use during operation
    @inlinable
    public func listDomains(
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListDomainsResponse {
        let input = ListDomainsRequest(
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.listDomains(input, logger: logger)
    }

    /// Returns a paginated list of objectives from the Control Catalog. You can apply an optional filter to see the objectives that belong to a specific domain. If you don’t provide a filter, the operation returns all objectives.
    @Sendable
    @inlinable
    public func listObjectives(_ input: ListObjectivesRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListObjectivesResponse {
        try await self.client.execute(
            operation: "ListObjectives", 
            path: "/objectives", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns a paginated list of objectives from the Control Catalog. You can apply an optional filter to see the objectives that belong to a specific domain. If you don’t provide a filter, the operation returns all objectives.
    ///
    /// Parameters:
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - nextToken: The pagination token that's used to fetch the next set of results.
    ///   - objectiveFilter: An optional filter that narrows the results to a specific domain. This filter allows you to specify one domain ARN at a time. Passing multiple ARNs in the ObjectiveFilter isn’t supported.
    ///   - logger: Logger use during operation
    @inlinable
    public func listObjectives(
        maxResults: Int? = nil,
        nextToken: String? = nil,
        objectiveFilter: ObjectiveFilter? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListObjectivesResponse {
        let input = ListObjectivesRequest(
            maxResults: maxResults, 
            nextToken: nextToken, 
            objectiveFilter: objectiveFilter
        )
        return try await self.listObjectives(input, logger: logger)
    }
}

extension ControlCatalog {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are not public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: ControlCatalog, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension ControlCatalog {
    /// Return PaginatorSequence for operation ``listCommonControls(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listCommonControlsPaginator(
        _ input: ListCommonControlsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListCommonControlsRequest, ListCommonControlsResponse> {
        return .init(
            input: input,
            command: self.listCommonControls,
            inputKey: \ListCommonControlsRequest.nextToken,
            outputKey: \ListCommonControlsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listCommonControls(_:logger:)``.
    ///
    /// - Parameters:
    ///   - commonControlFilter: An optional filter that narrows the results to a specific objective. This filter allows you to specify one objective ARN at a time. Passing multiple ARNs in the CommonControlFilter isn’t supported.
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - logger: Logger used for logging
    @inlinable
    public func listCommonControlsPaginator(
        commonControlFilter: CommonControlFilter? = nil,
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListCommonControlsRequest, ListCommonControlsResponse> {
        let input = ListCommonControlsRequest(
            commonControlFilter: commonControlFilter, 
            maxResults: maxResults
        )
        return self.listCommonControlsPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listControlMappings(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listControlMappingsPaginator(
        _ input: ListControlMappingsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListControlMappingsRequest, ListControlMappingsResponse> {
        return .init(
            input: input,
            command: self.listControlMappings,
            inputKey: \ListControlMappingsRequest.nextToken,
            outputKey: \ListControlMappingsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listControlMappings(_:logger:)``.
    ///
    /// - Parameters:
    ///   - filter: An optional filter that narrows the results to specific control mappings based on control ARNs, common control ARNs, or mapping types.
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - logger: Logger used for logging
    @inlinable
    public func listControlMappingsPaginator(
        filter: ControlMappingFilter? = nil,
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListControlMappingsRequest, ListControlMappingsResponse> {
        let input = ListControlMappingsRequest(
            filter: filter, 
            maxResults: maxResults
        )
        return self.listControlMappingsPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listControls(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listControlsPaginator(
        _ input: ListControlsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListControlsRequest, ListControlsResponse> {
        return .init(
            input: input,
            command: self.listControls,
            inputKey: \ListControlsRequest.nextToken,
            outputKey: \ListControlsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listControls(_:logger:)``.
    ///
    /// - Parameters:
    ///   - filter: An optional filter that narrows the results to controls with specific implementation types or identifiers. If you don't provide a filter, the operation returns all available controls.
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - logger: Logger used for logging
    @inlinable
    public func listControlsPaginator(
        filter: ControlFilter? = nil,
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListControlsRequest, ListControlsResponse> {
        let input = ListControlsRequest(
            filter: filter, 
            maxResults: maxResults
        )
        return self.listControlsPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listDomains(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listDomainsPaginator(
        _ input: ListDomainsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListDomainsRequest, ListDomainsResponse> {
        return .init(
            input: input,
            command: self.listDomains,
            inputKey: \ListDomainsRequest.nextToken,
            outputKey: \ListDomainsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listDomains(_:logger:)``.
    ///
    /// - Parameters:
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - logger: Logger used for logging
    @inlinable
    public func listDomainsPaginator(
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListDomainsRequest, ListDomainsResponse> {
        let input = ListDomainsRequest(
            maxResults: maxResults
        )
        return self.listDomainsPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listObjectives(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listObjectivesPaginator(
        _ input: ListObjectivesRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListObjectivesRequest, ListObjectivesResponse> {
        return .init(
            input: input,
            command: self.listObjectives,
            inputKey: \ListObjectivesRequest.nextToken,
            outputKey: \ListObjectivesResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listObjectives(_:logger:)``.
    ///
    /// - Parameters:
    ///   - maxResults: The maximum number of results on a page or for an API request call.
    ///   - objectiveFilter: An optional filter that narrows the results to a specific domain. This filter allows you to specify one domain ARN at a time. Passing multiple ARNs in the ObjectiveFilter isn’t supported.
    ///   - logger: Logger used for logging
    @inlinable
    public func listObjectivesPaginator(
        maxResults: Int? = nil,
        objectiveFilter: ObjectiveFilter? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListObjectivesRequest, ListObjectivesResponse> {
        let input = ListObjectivesRequest(
            maxResults: maxResults, 
            objectiveFilter: objectiveFilter
        )
        return self.listObjectivesPaginator(input, logger: logger)
    }
}

extension ControlCatalog.ListCommonControlsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> ControlCatalog.ListCommonControlsRequest {
        return .init(
            commonControlFilter: self.commonControlFilter,
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension ControlCatalog.ListControlMappingsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> ControlCatalog.ListControlMappingsRequest {
        return .init(
            filter: self.filter,
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension ControlCatalog.ListControlsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> ControlCatalog.ListControlsRequest {
        return .init(
            filter: self.filter,
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension ControlCatalog.ListDomainsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> ControlCatalog.ListDomainsRequest {
        return .init(
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension ControlCatalog.ListObjectivesRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> ControlCatalog.ListObjectivesRequest {
        return .init(
            maxResults: self.maxResults,
            nextToken: token,
            objectiveFilter: self.objectiveFilter
        )
    }
}
